package com.atguigu.order.config;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.HashMap;
import java.util.Map;

/**
 * description: MyMQConfig
 * date: 2022/12/28 18:30
 * author: MR.孙
 */
@Slf4j
@Configuration
public class MyMQConfig {

    //容器中的 Binding、Queue、Exchange 都会自动创建(RabbitMQ没有的情况)
    // RabbitMQ只要有，@Bean声明的属性发生变化也不会覆盖


    /**
     * 声明延时队列
     * @return
     */
    @Bean
    public Queue orderDelayQueue(){
        //String name, boolean durable, boolean exclusive, boolean autoDelete,
        //Map<String, Object> arguments
        Map<String, Object> arguments  = new HashMap<>();
        arguments.put("x-dead-letter-exchange", "order-event-exchange");
        arguments.put("x-dead-letter-routing-key", "order.release.order");
        arguments.put("x-message-ttl", 60000);
        return new Queue("order.delay.queue", true, false, false,arguments);
    }

    /**
     * 声明关闭订单队列
     * @return
     */
    @Bean
    public Queue orderReleaseOrderQueue(){
        return new Queue("order.release.order.queue", true, false, false);
    }

    /**
     * 声明交换机
     * @return
     */
    @Bean
    public Exchange orderEventExchange(){
        return new TopicExchange("order-event-exchange", true, false);
    }

    /**
     * 绑定队列和交换机 order.delay.queue和order-event-exchange
     * @return
     */
    @Bean
    public Binding orderCreateOrderBinding(){
        //String destination, DestinationType destinationType, String exchange, String routingKey,
        //@Nullable Map<String, Object> arguments
        return new Binding("order.delay.queue", Binding.DestinationType.QUEUE,
                "order-event-exchange", "order.create.order", null);
    }

    /**
     * 绑定队列和交换机 order.release.order.queue和order-event-exchange
     * @return
     */
    @Bean
    public Binding orderReleaseBinding(){
        return new Binding("order.release.order.queue",  Binding.DestinationType.QUEUE,
                "order-event-exchange", "order.release.order", null);
    }


    /**
     *存在问题：由于机器卡顿、消息延迟等导致关单消息未延迟发送，解锁库存消息正常发送和监听，导致解锁库存消息被消费，当执行完关单操作后便无法再执行解锁库存操作，导致卡顿的订单永远无法解锁库存。
     *解决方案：采取主动补偿的策略。当关单操作正常完成之后，主动去发送解锁库存消息给MQ，监听解锁库存消息进行解锁。
     * @return
     */
    @Bean
    public Binding orderReleaseOrderBinding() {
        return new
                Binding("stock.release.stock.queue", Binding.DestinationType.QUEUE,
                    "order-event-exchange", "order.release.other.#", null
                );
    }


    /**
     * 商品秒杀队列
     * @return
     */
    @Bean
    public Queue orderSecKillOrrderQueue() {
        Queue queue = new Queue("order.seckill.order.queue", true, false, false);
        return queue;
    }

    @Bean
    public Binding orderSecKillOrrderQueueBinding() {
        //String destination, DestinationType destinationType, String exchange, String routingKey,
        // 			Map<String, Object> arguments
        Binding binding = new Binding(
                "order.seckill.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.seckill.order",
                null);

        return binding;
    }



}
